package com.dynamicthreadpool.netty.handler;

import com.dynamicthreadpool.core.DynamicThreadPool;
import com.dynamicthreadpool.dubbo.DynamicThreadPoolFactory;
import com.dynamicthreadpool.manager.ThreadPoolManager;
import com.dynamicthreadpool.netty.protocol.ThreadPoolControlMessage;
import com.dynamicthreadpool.spi.URL;
import java.util.concurrent.Executor;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池控制消息处理器
 */
public class ThreadPoolControlHandler extends ChannelInboundHandlerAdapter {
    
    private final ThreadPoolManager threadPoolManager;
    private final String accessToken;
    
    /**
     * 构造函数，使用默认的空accessToken
     */
    public ThreadPoolControlHandler() {
        this(null);
    }
    
    /**
     * 构造函数
     * @param accessToken 访问令牌，用于身份验证
     */
    public ThreadPoolControlHandler(String accessToken) {
        this.threadPoolManager = ThreadPoolManager.getInstance();
        this.accessToken = accessToken;
    }
    
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof ThreadPoolControlMessage) {
            ThreadPoolControlMessage request = (ThreadPoolControlMessage) msg;
            
            // 验证accessToken
            if (!validateAccessToken(request.getAccessToken())) {
                ThreadPoolControlMessage response = new ThreadPoolControlMessage();
                response.setOperation(request.getOperation());
                response.setPoolId(request.getPoolId());
                response.setStatus("error");
                response.setMessage("Authentication failed: invalid access token");
                ctx.writeAndFlush(response);
                return;
            }
            
            ThreadPoolControlMessage response = handleRequest(request);
            ctx.writeAndFlush(response);
        }
    }
    
    /**
     * 验证访问令牌
     * @param token 客户端提供的令牌
     * @return 验证是否通过
     */
    private boolean validateAccessToken(String token) {
        // 如果服务器没有配置accessToken，则允许任何请求
        if (accessToken == null || accessToken.isEmpty()) {
            return true;
        }
        
        // 否则验证客户端提供的token是否匹配
        return accessToken.equals(token);
    }
    
    private ThreadPoolControlMessage handleRequest(ThreadPoolControlMessage request) {
        ThreadPoolControlMessage response = new ThreadPoolControlMessage();
        response.setPoolId(request.getPoolId());
        response.setOperation(request.getOperation());
        
        try {
            String operation = request.getOperation();
            String poolId = request.getPoolId();
            
            switch (operation) {
                case "create":
                    handleCreate(poolId, request.getParameters(), response);
                    break;
                case "update":
                    handleUpdate(poolId, request.getParameters(), response);
                    break;
                case "shutdown":
                    handleShutdown(poolId, response);
                    break;
                case "status":
                    handleStatus(poolId, response);
                    break;
                default:
                    response.setStatus("error");
                    response.setMessage("Unsupported operation: " + operation);
            }
        } catch (Exception e) {
            response.setStatus("error");
            response.setMessage("Error handling request: " + e.getMessage());
            e.printStackTrace();
        }
        
        return response;
    }
    
    private void handleCreate(String poolId, Map<String, String> parameters, ThreadPoolControlMessage response) {
        try {
            // 将参数转换为URL对象
            URL url = new URL("dynamic", "localhost", 8080, null, parameters);
            
            // 使用DynamicThreadPoolFactory创建线程池
            DynamicThreadPoolFactory factory = new DynamicThreadPoolFactory();
            DynamicThreadPool threadPool = (DynamicThreadPool) factory.getExecutor(url);
            
            // 注册线程池到管理器
            threadPoolManager.registerThreadPool(poolId, threadPool);
            
            response.setStatus("success");
            response.setMessage("Thread pool created successfully: " + poolId);
            // 添加线程池状态信息
            addPoolStatusInfo(threadPool, response);
        } catch (Exception e) {
            response.setStatus("error");
            response.setMessage("Error creating thread pool: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    private void handleUpdate(String poolId, Map<String, String> parameters, ThreadPoolControlMessage response) {
        try {
            // 检查线程池是否存在
            Executor executor = threadPoolManager.getThreadPool(poolId);
            if (executor == null) {
                response.setStatus("error");
                response.setMessage("Thread pool not found: " + poolId);
                return;
            }
            
            // 将参数转换为URL对象
            URL url = new URL("dynamic", "localhost", 8080, null, parameters);
            
            // 更新线程池
              threadPoolManager.updateThreadPool(poolId, url);
            
            // 获取更新后的线程池状态
            if (executor instanceof DynamicThreadPool) {
                DynamicThreadPool threadPool = (DynamicThreadPool) executor;
                response.setStatus("success");
                response.setMessage("Thread pool updated successfully: " + poolId);
                addPoolStatusInfo(threadPool, response);
            } else {
                response.setStatus("error");
                response.setMessage("Thread pool is not of type DynamicThreadPool: " + poolId);
            }
        } catch (Exception e) {
            response.setStatus("error");
            response.setMessage("Error updating thread pool: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    private void handleShutdown(String poolId, ThreadPoolControlMessage response) {
        try {
            // 注销并关闭线程池
            threadPoolManager.unregisterThreadPool(poolId);
            
            response.setStatus("success");
            response.setMessage("Thread pool shutdown successfully: " + poolId);
        } catch (Exception e) {
            response.setStatus("error");
            response.setMessage("Error shutting down thread pool: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    private void handleStatus(String poolId, ThreadPoolControlMessage response) {
        try {
            Executor executor = threadPoolManager.getThreadPool(poolId);
            
            if (executor instanceof DynamicThreadPool) {
                DynamicThreadPool threadPool = (DynamicThreadPool) executor;
                response.setStatus("success");
                response.setMessage("Thread pool status retrieved successfully: " + poolId);
                addPoolStatusInfo(threadPool, response);
            } else if (executor == null) {
                response.setStatus("error");
                response.setMessage("Thread pool not found: " + poolId);
            } else {
                response.setStatus("error");
                response.setMessage("Thread pool is not of type DynamicThreadPool: " + poolId);
            }
        } catch (Exception e) {
            response.setStatus("error");
            response.setMessage("Error retrieving thread pool status: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    private void addPoolStatusInfo(DynamicThreadPool threadPool, ThreadPoolControlMessage response) {
        Map<String, Object> statusInfo = new HashMap<>();
        
        if (threadPool instanceof ThreadPoolExecutor) {
            ThreadPoolExecutor executor = (ThreadPoolExecutor) threadPool;
            statusInfo.put("activeCount", executor.getActiveCount());
            statusInfo.put("corePoolSize", executor.getCorePoolSize());
            statusInfo.put("maximumPoolSize", executor.getMaximumPoolSize());
            statusInfo.put("poolSize", executor.getPoolSize());
            statusInfo.put("queueSize", executor.getQueue().size());
            statusInfo.put("taskCount", executor.getTaskCount());
            statusInfo.put("completedTaskCount", executor.getCompletedTaskCount());
            statusInfo.put("isShutdown", executor.isShutdown());
            statusInfo.put("isTerminated", executor.isTerminated());
        }
        
        response.setPoolStatus(statusInfo);
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}